﻿using Abp.Domain.Repositories;
using Abp.Domain.Services;
using Abp.UI;
using shenghua.Member.Coupons;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace shenghua.Marketing.Coupons
{
    public class CouponManager: DomainService
    {
        private readonly IRepository<Coupon> _couponRepository;
        private readonly IRepository<MemberCoupon> _memberCouponRepository;
        private readonly GrantCouponLogManager _grantCouponLogManager;

        public CouponManager(
            IRepository<Coupon> couponRepository,
            IRepository<MemberCoupon> memberCouponRepository,
            GrantCouponLogManager grantCouponLogManager
            )
        {
            _couponRepository = couponRepository;
            _memberCouponRepository = memberCouponRepository;
            _grantCouponLogManager = grantCouponLogManager;
        }

        public async Task<Coupon> Get(int id)
        {
            Coupon item = await _couponRepository.GetAsync(id);
            return item;
        }
        
        public async Task<Coupon> Add(Coupon coupon)
        {
            await _couponRepository.InsertAsync(coupon);
            return coupon;
        }

        public async Task<Coupon> Update(Coupon coupon)
        {
            await _couponRepository.UpdateAsync(coupon);
            return coupon;
        }

        public async Task Delete(int id)
        {
            await _couponRepository.DeleteAsync(id);
        }

        /// <summary>
        /// 将优惠券发放给指定会员
        /// </summary>
        /// <param name="coupon"></param>
        /// <param name="member"></param>
        /// <returns></returns>
        public async Task<MemberCoupon> GrantCoupon(Coupon coupon, Member.Members.Member member)
        {
            if (!coupon.HasRest)
            {
                throw new UserFriendlyException("优惠券已经发放完毕");
            }
            if(IsReceived(member.Id, coupon.Id))
            {
                throw new UserFriendlyException("已经领取过该优惠券啦");
            }
            coupon.GrantedCount += 1;
            _couponRepository.Update(coupon);

            MemberCoupon memberCoupon = new MemberCoupon
            {
                MemberId = member.Id,
                Amount = coupon.Amount,
                AppliedCommodityIds = coupon.AppliedCommodityIds,
                Name = coupon.Name,
                Status = MemberCouponStatus.Unused,
                Condition = coupon.Condition,
                TargetType = coupon.TargetType,
                TimeLimit = coupon.TimeLimit,
                CouponId = coupon.Id
            };
            _memberCouponRepository.Insert(memberCoupon);

            await _grantCouponLogManager.Add(member, coupon);

            return memberCoupon;
        }

        public bool IsReceived(long memberId, int couponId)
        {
            return _memberCouponRepository.GetAll().Where(r => r.MemberId == memberId && r.CouponId == couponId).Count() > 0;
        }

        public async Task DeleteMemberCoupon(long memberId, int memberCouponId)
        {
            var item = _memberCouponRepository.GetAll().Where(r => r.MemberId == memberId && r.Id == memberCouponId).FirstOrDefault();
            if(item == null)
            {
                throw new UserFriendlyException("不存在的会员优惠券");
            }
            await _memberCouponRepository.DeleteAsync(item);
        }

        /// <summary>
        /// 是否已经发放给指定会员
        /// </summary>
        /// <param name="memberId"></param>
        /// <param name="couponId"></param>
        /// <returns></returns>
        public async Task<bool> IsGrantedForMember(long memberId, int couponId)
        {
            return await _grantCouponLogManager.IsGrantedForMember(memberId, couponId);
        }

        /// <summary>
        /// 优惠券被使用
        /// </summary>
        /// <param name="couponId"></param>
        /// <returns></returns>
        public async Task IsUsedByMember(int couponId)
        {
            var coupon = _couponRepository.Get(couponId);
            coupon.UsedCount += 1;
            await _couponRepository.UpdateAsync(coupon);
        }
    }
}
